package logview;

import java.util.ArrayList;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import logview.mbeans.LogFileManager;
import logview.mbeans.PropertyLogFile;

public class InitServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static transient final java.util.logging.Logger log = java.util.logging.Logger.getLogger(InitServlet.class.getName());

	public static final String DOMAIN = "logview_"+System.currentTimeMillis();
	private MBeanServer server;
	public static String agentId;
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		String filename = config.getServletContext().getRealPath("WEB-INF/logfiles.properties");
		log.fine(InitServlet.class.getName()+" initialized");
		
		createMBeanServer();
		// Add core mbeans
		LogFileManager manager = new LogFileManager();
		ObjectName on = LogFileManager.getObjectName();
		try {
			server.registerMBean(manager, on);
		} catch (Exception e1) {
			log.warning("Error registering "+on);
		}

		// Add MBeans for loggers in logfiles.properties
		try {
			PropertyLogFile logfiles = new PropertyLogFile();
			logfiles.setFilename(filename);
			logfiles.addAll();
			ObjectName objectName = logfiles.getObjectName();
			try {
				server.registerMBean(logfiles, objectName);
			} catch (Exception e1) {
				log.info("Error registering "+objectName+": "+ e1);
			}
		} catch (IllegalArgumentException unused) {
			// probably file does not yet exist
			log.fine("NOT AN ERROR: "+ unused);
		}

	}

	private synchronized void createMBeanServer() {
		if (server == null) {
			server = MBeanServerFactory.createMBeanServer(DOMAIN);

			try {
				agentId = (String) server.getAttribute(ObjectName.getInstance("JMImplementation:type=MBeanServerDelegate"), "MBeanServerId");
				log.info("MBeanServer agent id: "+agentId);
			} catch (Exception e) {
				log.severe("Caught exception in class InitServlet, method createMBeanServer: "+ e);
				throw new RuntimeException("Error creating MBeanServer: "+e);
			}
		}
	}
	
	@Override
	public void destroy() {
		log.fine(InitServlet.class.getName()+" destroyed");
		super.destroy();
		MBeanServerFactory.releaseMBeanServer(this.server);
	}
	
	@SuppressWarnings("unchecked")
	public static MBeanServer getMBeanServer() {
		ArrayList srv = MBeanServerFactory.findMBeanServer(InitServlet.agentId);
		log.fine(""+srv);
		if (srv!=null && srv.size()==1) {
			log.fine("OK, MBeanServer found");
			return (MBeanServer) srv.get(0);
		} else if (srv!=null && srv.size()>1) {
			for (Object object : srv) {
				MBeanServer s = (MBeanServer) object;
				if (s.getDefaultDomain().equals(DOMAIN)) {
					log.fine("OK, MBeanServer found");
					return s;
				}
			}
		}
		log.severe("findMBeanServer did returned "+srv==null?""+0:srv.size()+" servers instead of 1");
		return null;
	}
}
